Amazon Redshift データ消失からのトラブルシューティング
DBを利用していると、不正なデータ投入やオペレーションミスなど様々な理由によって、データ破壊や消失といったトラブルに見舞われることがあります。今回はRedshiftにおけるデータ破壊・消失から復旧する方法についてを解説します。
バックアップについて
データを復旧するためにはもちろんバックアップの取得が不可欠です。Redshiftのバックアップは以下の方法が考えられます。
- 自動スナップショット
- 手動スナップショット
- UNLOADコマンドによるS3ファイルバックアップ
Redshiftでは、「スナップショット」といって、更新データを増分バックアップする仕組みが標準で提供されています。DDLやデータの更新情報といったクラスタを構成するユーザー、スキーマ、オブジェクト(テーブルやビュー、UDF等)の復旧に必要となる情報は全て含まれておりますが、一時テーブルや中間テーブルに対する書き込みのような復旧に不要なデータは含まれないといった優れたものです。スナップショットは、後述するクラスタのリストアやテーブル単位のリストア等、データ復旧の中心的な存在です。
スナップショットのAWS利用費は、スナップショットのサイズによって課金されますが、クラスタのストレージサイズまで無料です。更新データ量を試算して、それに応じて保持期間を設定すると料金発生を抑えて利用できます。本来、頻繁なデータ更新や大規模なデータの入れ替えが発生しないDWH用途では、スナップショットのサイズがクラスタのストレージサイズを超えることは多くありません。よって、一般的なDWH用途では、1〜2週間程度に保存することをおすすめしています。Redshiftクラスタがハードウェア障害から復旧するにはスナップショットのリストアとなりますので、必ず自動スナップショットは有効(保存期間1日以上)に設定してください。
自動スナップショット
Redshiftでは、自動的にバックアップを取得する方法として、「自動スナップショット」が提供されています。マネジメントコンソールからクラスタを作成すると、保存期間1日(デフォルト)として設定されます。保存期間は0〜35日間で変更可能です。自動スナップショットは、約8時間毎もしくは5GB以上の更新が生じたときに自動的に取得し、保存期間を経過すると自動的にローテーションされます。注意点は、クラスタを削除すると一緒に削除されるので、保存したい場合には事前に自動スナップショットから手動スナップショットを作成してください。
マネジメントコンソールから保存期間を変更するには「クラスタの変更」ダイアログで、「自動スナップショット保存期間」を変更します。
手動スナップショット
Redshiftでは、任意のタイミングでバックアップを取得する方法として、「手動スナップショット」が提供されています。マネジメントコンソールやAPI(AWSCLI、AWS SDK等)を利用して、スナップショットを取得できます。
自動スナップショットに対して、手動スナップショットを利用するユースケースは以下のとおりです。
- バックアップを取得する時間が決まっている場合やデータ更新の後のバックアップ等、任意のタイミングでスナップショットを取得したい
- 35日を超えるスナップショットを保存したい
- 自動スナップショットをコピーして、手動スナップショットを作成したい
手動スナップショットのデフォルト取得上限値は「20」となりますので、保存するスナップショットが20を超える可能性がある場合は、事前に上限緩和申請をしたほうが良いでしょう。また、手動スナップショットは自動的に削除されませんので、不要になったら削除してください。
UNLOADコマンドによるS3ファイルバックアップ
DBに依存しない伝統的なCSV/TSVファイルにバックアップする方法です。RedshiftではUNLOADコマンドを利用して、CSV/TSV形式で高速にパラレルでダンプすることが可能です。テーブル毎のフルバックアップが主な用途になりますので、データマートなど集計に時間を要したデータで、データサイズは小さなテーブルのバックアップに効果的です。
データ消失からのデータ復旧
方法1:スナップショットからのテーブルのリストア
スナップショットからテーブル単位でリストアする機能です。一部のテーブルのデータのみを復旧するユースケースに向いています。データを復旧しなければならない時、第一候補として「テーブルのリストア」を利用できないかご検討ください。
テーブルのリストア
スナップショットからのリストアは『クラスタ全体』が一般的ですが、この機能を使う事によってテーブル単位でのリストアが可能です。開発中に「やっちまった」というときはホント便利です。
マネジメントコンソールからテーブルリストアを実行するにはクラスタの[Table restore]タブの[テーブルの復元]ボタンを押して、ダイアログの内容に従いリストアします。
テーブルリストアの詳細な手順は、以下のブログを御覧ください。
リストア対象テーブルに対する権限や参照しているビューを維持するには
リストア先のテーブルが存在するとエラーとなりますので、リストア先のテーブルを削除した後、同じテーブル名でリストアするのが一般的です。しかし、一度テーブルを削除してしまうとテーブルに対する権限やテーブルを参照しているビューの削除等の影響が懸念されます。この問題を回避するには、別のテーブル名でリストアした後、リストア先のテーブルにコピーをすることで元のテーブル削除を回避できます。
制限事項
- リサイズやノードタイプ変更前のスナップショットからのリストアテーブルはできません
- カラム名にマルチバイト(日本語など)を含む場合、テーブルリストアはできません
方法2:スナップショットからのクラスタのリストア
スナップショットからクラスタの複製を作成することでデータ復旧します。テーブルの復旧で対処できない場合やデータの復旧が広範囲に渡る場合は、クラスタのリストアによって、データを消失する直近のクラスタを作成します。
1.クラスタのリストア
マネジメントコンソールのスナップショットの一覧から選択して、「スナップショットの復元」を選択すると以下のダイアログが表示されます。リストア先のクラスター識別子が存在するとエラーとなりますので、異なるものを設定します。
2.データを直前の状態に戻す
スナップショット取得時点から現在までの更新情報を更新用の定期バッチを再実行して適用します。(表領域のリストア、WALによるロールフォワードという選択肢はありません。)定期バッチはこのようなトラブルにも迅速かつ的確に対処できるように冪等性を確保できるように設計しましょう。
3.既存クラスタとリストアしたクラスタの置き換え
リストアしたクラスタは、クラスター識別子(=データベースへの接続先)が異なるので、これまで接続していたアプリケーションやBIツールからは既存のクラスタを参照したままです。アプリケーションやBIツールに影響がないように新旧クラスタを切り替える方法を2つご紹介します。
Privete DNS による接続先クラスタの切り替え
クラスタの柔軟な切り替えを想定して、データベースへの接続先(=クラスター識別子)にCNAMEを設定している場合は、CNAMEの値を変更するだけで切り替え完了です。データベースへの接続先にCNAMEを設定する方法は、以下のブログを御覧ください。
クラスター識別子のスワップ
新旧クラスタのクラスター識別子を入れ替えることで、新旧クラスタを切り替えます。クラスター識別子は以下の通り、マネジメントコンソールの「クラスタの変更」ダイアログから変更できます。
4.EIPの付け替え
EIPを付与している場合は既存のクラスタからリストアしたクラスタへ別途付け替えてください。マネジメントコンソールの「クラスタの変更」ダイアログから可能です。
5.既存クラスタの削除のタイミング
スナップショットの中に既存のVPCやサブネットグループ、セキュリティグループ、DBパラメタ等の設定情報を含んでいませんので、全てのルートからの接続が可能であるか、リストア前の性能要件が満たせているか等の確認が終わる前に削除することはおすすめできません。
また、既存クラスタを削除すると、付随する自動スナップショットも一緒に削除します。リストアしたいスナップショットが異なっていた場合、スナップショットがないという事態に陥ります。それでも削除しなければならない場合は、自動スナップショットを手動スナップショットして保存しておきましょう。
方法3:S3ファイルからリストア
データソースとなるCSVファイルや事前にUNLOADしたCSV/TSVファイルをロード(COPY)してデータを復旧します。データソースとなるCSV/TSVファイルは基本的にS3においてロードします。(他のデータソースからロードしたい場合はこちらを御覧ください)UNLOAD/COPYコマンドは、以下のビューを参考することで簡単にUNLOAD/COPYのSQLを自動生成できます。
Redshiftで作成したデータマートを他のシステムに連携するユースケースでは、既存の運用フローの中でデータマートなどのテーブルをすでにUNLOADして連携して事が考えられます。このユースケースでは連携で利用しているファイルが、同時にバックアップでもあるというのが理想的です。 DBに依存しない伝統的なCSV/TSVによるバックアップ・リストアを好む方にとってはこちらの方法が一番わかり易いかもしれません。
最後に
新旧色々とご紹介しましたが、データ消失した場合は以下の優先順位で対策をご検討ください。
- 方法1:スナップショットからのテーブルのリストア
- 方法3:S3ファイルからリストア
- 方法2:スナップショットからのクラスタのリストア
テーブルデータを復旧するのであれば、方法1もしくは方法3をご検討ください。これ以外の場合は方法2となりますが、実際には手順が多く影響が大きいため、クラスタをリストアしたとしても、既存のクラスタを利かす選択肢を常に考えたほうが良いでしょう。Redshiftのバックアップにおいてスナップショットの取得がいかに重要であるかはご理解いただけたのではないかと思いますので、少なくとも自動スナップショットは必ず設定してください。